#include <msg/request.h>
#include <router/RouterClient.h>
#include <router/RouterResponse.h>
#include <router/RouterServer.h>
#include <iostream>
#include <fcntl.h>

RouterServer::RouterServer(uint16_t server_port):
    server(server_port),
    ep(40960),
    client_table(RouterClient::ROUTERCLIENT_ID)
{
    int flags = fcntl(server.get_sockfd(), F_GETFL, 0);
    fcntl(server.get_sockfd(), F_SETFL, flags | O_NONBLOCK);

    epoll_data_t data;
    data.fd = server.get_sockfd();
    ep.epoll_add(static_cast<EPOLL_EVENTS>(EPOLLIN | EPOLLET), server.get_sockfd(), data);
}

void RouterServer::start(){
    thread_pool.start();
    while (true)
    {
        int events_count = ep.epoll_wait(-1);
        if (events_count == -1)
        {
            perror("本次epoll_wait过程中发生了错误\n");
            continue;
        }

        for (int i = 0; i < events_count; ++i)
            thread_pool.submit(read_from_fd, this, ep[i].data);
    }
}

void RouterServer::accept_client(){
    while (true)
    {
        int client = this->server.accept();
        if (client < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                // 没有连接请求需要处理，可以做一些其他的事情
                // ...
            } else {
                // 出现错误，需要进行错误处理
                // ...
            }
            break;
        } 
        else {
            // 由于server的套接字设置为了非阻塞模式
            // accept()得到的client也是非阻塞的
            epoll_data_t data;
            data.fd = client;
            this->ep.epoll_add(static_cast<EPOLL_EVENTS>(EPOLLIN | EPOLLET), client, data);
        }
    }
    



}

void RouterServer::hand_request(int fd, message msg){
    if (msg.get_router_info().message_type != MessageType::REQUEST){
        return;
    }

    request req(msg);
    switch (req.get_head().op)
    {
        using enum request_op;
    case LOG_IN:{
        Endpoint from = msg.get_router_info().from;
        from.app = RouterClient::ROUTERCLIENT_ID;
        response_code code;
        if (client_table.contain(from)){
            code = response_code::FAILED;
        }
        else{
            code = response_code::SUCCESS;
            client_table.add_client(fd, from);
        }
        response resp = RouterResponse::make_response(req, code);
        
        message::write_message_to(resp, fd);
        break;
    }
    default:{
        response resp = RouterResponse::make_response(req, response_code::UNKNOWN_OP);
        message::write_message_to(resp, fd);
        break;
    }
    }

    // 目前只会接收到登陆请求
    // 这里只是简单验证


        // 检查是不是请求，只能接收请求
        // 如果是发送给我的请求
        // 登录  登出

        // 等入  添加到 endpoint_to_fd
        // 登出  删除 endpoint_to_fd

        // 异常情况
        // 登入  已存在
        // 登出  已登出
}

void RouterServer::hand_forward(message msg){
    auto to = msg.get_router_info().to;
    to.app = RouterClient::ROUTERCLIENT_ID;
    if (this->client_table.contain(to) == false){
        // 如果转发对象不存在
        printf("目的地不可达\n");
        return;
    }

    message::write_message_to(msg, this->client_table.get(msg.get_router_info().to));
}

void RouterServer::read_from_fd(RouterServer* router, epoll_data_t data){
    if (data.fd == router->server.get_sockfd()){
        // 有新应用连接    
        router->accept_client();
        return;
    }
    
    auto [msg, is_valid] = message::read_message_from(data.fd);
    if (is_valid == false){
        perror("客户端断开连接");
        close(data.fd);
        router->client_table.rm_client(data.fd);
        return;
    }
    if (msg.get_router_info().to == router->SERVER_ENDPOINT){
        // 如果是发送给我的
        // 除了请求  还有可能是心跳包
        router->hand_request(data.fd, msg);
        return;
    }

    // 否则则是需要我转发的
    router->hand_forward(msg);
}
    

